#!/usr/bin/env python

# Copyright (C) 2010 Zajcev Evgeny <zevlg@yandex.ru>

# Test suite for osmiip's ``is_inside``
# usage: ./test_is_inside.py [-s] [-n <DOTS>] <poly-file>
# NOTE: requires gnuplot

import sys, getopt, os, random, tempfile, time
from itertools import imap
from functools import partial

map(sys.path.append, ["./", "../", "../src"])

from osmt import make_polygon

PNTS = 200000

def usage():
    print "usage: %s [-s] [-n <DOTS>] <poly-file>"%sys.argv[0]
    print "\t-s\tis_inside speed test"
    print "\t-n <DOTS>\tnumber of dots (default: %d)"%PNTS
    sys.exit(0)

try:
    opts, sargs = getopt.getopt(sys.argv[1:], "sn:")
except getopt.GetoptError, err:
    print str(err)
    usage()

if len(sargs) is not 1:
    usage()

sflag = False
for o,v in opts:
    if o == '-n':
        PNTS = int(v)
    elif o == '-s':
        sflag = True


def verbose(str):
    sys.stdout.write(str)
    sys.stdout.flush()

def rand_point(nu):
    return xmin + random.random()*xrng, ymin + random.random()*yrng

def write_pnt(fd, (x,y)):
    os.write(fd, "%f %f\n"%(x,y))

def print_hits(pp):
    gperc = (100*pp.ghits)/(pp.ghits+pp.wnhits+1)
    print "+ %d grid hits, %d wn hits: %d%%"%(pp.ghits, pp.wnhits, gperc)

verbose("+ Optimizing polygon.. ")
st = time.time()
pp = make_polygon(sargs[0])
ymin, xmin, ymax, xmax = pp.bounds()
yrng = ymax-ymin
xrng = xmax-xmin
print "%f seconds"%(time.time()-st)

if sflag:
    verbose("+ Checking is_inside() speed.. ")
    pnts = map(rand_point, xrange(PNTS))
    st = time.time()
    for rp in pnts:
        pp.is_inside(rp[0], rp[1])
    tm = time.time() - st
    print "%f seconds"%tm
    print "+ %d points / %f seconds = %d pps"%(PNTS, tm, PNTS/tm)
    print_hits(pp)
    sys.exit(0)

# Create temp files
(pf, pfn), (outf, outfn), (inf, infn) = \
     map(tempfile.mkstemp, ["poly", "out", "in"])

# write a polygon file
map(lambda (c,_): map(partial(write_pnt, pf), c), pp.contours)

# write in/out files
verbose("+ Writing %d points.. "%PNTS)
st = time.time()
for p in imap(rand_point, xrange(PNTS)):
    write_pnt(inf if apply(pp.is_inside, p) else outf, p)
print "%f seconds"%(time.time()-st)

# Close everything
map(os.close, (pf, outf, inf))

# Plot everything using gnuplot
gfd, gfn = tempfile.mkstemp("in")
plotpoly = "plot '%s' with lines lt rgb 'black' title '%s'"%(pfn,sys.argv[1])
map(lambda x: os.write(gfd, x+"\n"),
    ["set terminal x11",
     plotpoly,
     "replot '%s' with dots lt rgb '#FF6666' title 'outside'"%outfn,
     "pause 4",
     plotpoly,
     "replot '%s' with dots lt rgb '#00CC00' title 'inside'"%infn,
     "pause 5"])

os.close(gfd)
print "+ Launching gnuplot.."
os.system("gnuplot %s"%gfn)

print "+ Removing temporary files"
map(os.unlink, (pfn, outfn, infn, gfn))

# Display hit stats
print_hits(pp)
